<template>
  <div>
    <!-- <el-button type="primary" plain>请选择服务区域</el-button> -->
    <el-cascader
      v-model="selectedArea"
      :options="areaOptions"
      :props="cascaderProps"
      placeholder="请选择服务区域"
      :show-all-levels="false"
      multiple
      @change="handleChange"
      @expand-change="handleExpandChange"
    ></el-cascader>
    <!-- <div v-if="selectedArea.length > 0">
      <p>选择结果：{{ selectedResult }}</p>
    </div> -->
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from "vue";
import CommonAPI from "@/api/system/common";

const selectedArea = ref([]); // 选中的区域
const flatAreaOptions = ref([]); // 平铺的区域数据
const areaOptions = ref([]); // 树状的区域数据
const firstParentData = ref([]); // 第一级的数据
const props = defineProps({
  modelValue: {
    type: Array,
    default: () => [],
  },
  selectAreaText: {
    type: String,
    default: "",
  },
});
const emit = defineEmits(["update:modelValue"]);

const cascaderProps = reactive({
  expandTrigger: "click",
  value: "code",
  label: "name",
  //lazy: false,
  multiple: true,
  checkStrictly: true,
  emitPath: false,
  //lazyLoad: loadChildAreas,
});
function handleChange(newValue) {
  // 将数据按长度排序，确保从最长的（最低层级）开始处理
  newValue.sort((a, b) => b.length - a.length);

  // 用于存储最终结果
  const result = [];

  // 遍历排序后的数据
  for (const item of newValue) {
    // 检查是否已经有更长的子节点被选中
    let isParentOfSelected = false;
    for (const selected of result) {
      if (selected.startsWith(item)) {
        isParentOfSelected = true;
        break;
      }
    }

    // 如果当前节点不是其他已选节点的父级，则保留
    if (!isParentOfSelected) {
      result.push(item);
    }
  }
  selectedArea.value = result;
  emit("update:modelValue", selectedArea.value);
}
// 处理展开事件，动态加载子节点
function handleExpandChange(value) {
  // 通过当前节点的 value 找到对应的节点
  const node = findNode(areaOptions.value, value[0]);
  if (node && !node.children.length) {
    loadChildAreas(node.code).then((children) => {
      // 将子节点数据拼接到当前节点的 children 属性中
      node.children = reactive(children);
    });
  }
}

// 递归查找节点
function findNode(nodes, value) {
  for (const node of nodes) {
    if (node.code === value) {
      return node;
    }
    if (node.children) {
      const found = findNode(node.children, value);
      if (found) return found;
    }
  }
  return null;
}
// 加载子节点数据
async function loadChildAreas(parentCode) {
  try {
    const res = await CommonAPI.getArea(parentCode);
    const flatData = res.data;
    return flatData.map((item) => ({
      code: item.code,
      name: item.name,
      level: item.level,
      children: item.level < 3 ? [] : null, // 如果是省市区以下的层级，不加载子节点
    }));
  } catch (error) {
    console.error("Failed to load child area data:", error);
    return [];
  }
}

function convertToTree(data, parentCode) {
  return data
    .filter((item) => item.parentCode === parentCode)
    .map((item) => ({
      code: item.code,
      name: item.name,
      level: item.level,
      children: item.level < 3 ? convertToTree(data, item.code) : [],
    }));
}

/**
 * 有默认数据，获取默认数据的上级code
 * @param codes
 */
function handleDefaltData(codes) {
  const parents = new Set();
  // 生成所有上级code
  for (const code of codes) {
    if (code.length >= 4) {
      parents.add(code.substring(0, 2));
    }
    if (code.length >= 6) {
      parents.add(code.substring(0, 4));
    }
  }
  // 筛选存在子级的上级code
  const result = [];
  for (const parent of Array.from(parents)) {
    if (codes.some((code) => code !== parent && code.startsWith(parent))) {
      result.push(parent);
    }
  }
  return result;
}
/**
 * 处理默认数据，先拼接好 areaOptions
 */
watch(
  () => props.modelValue,
  async (newVal) => {
    if (!firstParentData.value.length) {
      // 存储第一级的数据
      const res = await fetchAndConvertData("0");
      firstParentData.value = res.data;
      flatAreaOptions.value = firstParentData.value;
      areaOptions.value = reactive(firstParentData.value);
    }
    // 有默认值就直接组装数据
    if (newVal.length) {
      let defaultData = handleDefaltData(newVal);
      Promise.all(defaultData.map((code) => fetchAndConvertData(code))).then((res) => {
        flatAreaOptions.value = [...firstParentData.value, ...res.data.flat()];
        areaOptions.value = reactive(convertToTree(flatAreaOptions.value, "0"));
        selectedArea.value = newVal;
      });
    }
  },
  { immediate: true }
);
async function fetchAndConvertData(parentCode) {
  try {
    return await CommonAPI.getArea(parentCode);
  } catch (error) {
    console.error("Failed to load area data:", error);
  }
}
onMounted(() => {
  //areaOptions.value = fetchAndConvertData("0");
});
</script>
